/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.great.functionalCore;

import br.great.beans.FacebookProfile;
import br.great.beans.FacebookProfileString;
import br.great.config.FacebookData;
import br.great.config.PhotomapConstants;
import com.restfb.DefaultFacebookClient;
import com.restfb.FacebookClient;
import com.restfb.FacebookToken;
import com.restfb.TokenFile;
import com.restfb.json.JsonObject;
import com.restfb.types.Note;
import com.restfb.types.User;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

/**
 * 
 * @author Drazzco
 */
public class ObtainsFriendInference {
	ArrayList<FacebookProfileString> vtFacebookProfile;

	public ObtainsFriendInference() {
		vtFacebookProfile = new ArrayList<FacebookProfileString>();
	}

	// Esse método abre uma conexão com o Facebook e usa os métodos
	// saveUserFacebookProfile, getFriendsID, saveFriendsFacebookProfile
	// para guardar os dados capturados por eles em uma lista de
	// FacebookProfileString
	// que será usada pela classe SaveFacebookInstances.
	protected ArrayList<FacebookProfileString> generateFacebookProfile(String name) throws MalformedURLException, IOException {

		FacebookClient fc = new DefaultFacebookClient(FacebookToken.accessToken(TokenFile.getText(name)));
		ArrayList<String> id = getFriendsID(fc);
		vtFacebookProfile.add(0, saveUserFacebookProfile(fc));
		int size = id.size();
		for (int i = 0; i < id.size(); i++) {
			vtFacebookProfile.add(i + 1, saveFriendsFacebookProfile(fc, id.get(i)));
		}
		return vtFacebookProfile;
	}

	// Esse método captura os dados do usuário pegos na conexão com o facebook
	// e os retorna em um objeto FacebookProfileString.
	protected FacebookProfileString saveUserFacebookProfile(FacebookClient fc) {
		User user = fc.fetchObject("me", User.class);
		JsonObject mynotes = fc.fetchObject("me/notes", JsonObject.class);
		int bt = mynotes.getJsonArray("data").length();
		String bluetooth = null;
		int flag = 0;
		int count = 0;
		while ((flag == 0) && (count <= bt)) {
			Note mynote = fc.fetchObject(mynotes.getJsonArray("data").getJsonObject(count).getString("id"), Note.class);
			if (mynote.getSubject().contains("bluetooth")) {
				bluetooth = mynote.getMessage();
				flag = 1;
			} else {
				count++;
			}
		}
		FacebookProfileString user_fp = new FacebookProfileString();
		user_fp.setName(user.getName());
		user_fp.setBluetooth(bluetooth);
		// A data retornada pelo Facebook tem o formato "MM/dd/yyyy"
		// que não é retornada corretamente pelo java(eu acho),
		// por isso transformo essa data para o formato "dd/MM/yyyy".
		Date wDate = user.getBirthdayAsDate();
		String wDate2 = user.getBirthday();
		// Tratamento de erros da data:
		// Amigo do usuário que deixou a data nula
		if (wDate2 == null) {
			user_fp.setBirthday(wDate2);
			System.out.println(PhotomapConstants.NULLFACEBOOKDATEFORMAT);
		} else {
			String[] wDate3 = wDate2.split("(?<=\\G.{1})");
			// Amigo do usuário que não colocou o ano de nascimento, somente dia
			// e mês
			if (wDate3.length == 5) {
				user_fp.setBirthday(wDate2);
				System.out.println(PhotomapConstants.WRONGFACEBOOKDATEFORMAT);
			} else {
				DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
				String date = formatter.format(wDate);
				user_fp.setBirthday(date);
			}
		}
		return user_fp;
	}

	// Esse método retorna uma lista de strings contendo os ids dos
	// amigos do usuário que foram capturados na conexão com o facebook
	protected ArrayList<String> getFriendsID(FacebookClient fc) {
		ArrayList<String> id = new ArrayList<String>();
		JsonObject myfriends = fc.fetchObject("me/friends", JsonObject.class);
		int fr = myfriends.getJsonArray("data").length();

		for (int i = 0; i < fr; i++) {
			id.add(myfriends.getJsonArray("data").getJsonObject(i)
					.getString("id"));
		}
		return id;
	}

	// Esse método captura os dados dos amigos do usuário pegos na conexão com o
	// facebook
	// e os retorna em um objeto FacebookProfileString.
	protected FacebookProfileString saveFriendsFacebookProfile(
			FacebookClient fc, String id) {

		FacebookProfileString friends_fp = new FacebookProfileString();

		User friend = fc.fetchObject(id, User.class);
		JsonObject notes = fc.fetchObject(id + "/notes", JsonObject.class);

		int bt = notes.getJsonArray("data").length();
		String bluetooth = null;

		for (int count = 0; count < bt; count++) {
			Note note = fc.fetchObject(notes.getJsonArray("data")
					.getJsonObject(count).getString("id"), Note.class);
			if (note.getSubject().contains("bluetooth")) {
				bluetooth = note.getMessage();
				// flag = 1;
			}

		}

		friends_fp.setName(friend.getName());
		friends_fp.setBluetooth(bluetooth);
		// Mesma transformção do formato da data explicada no método
		// saveUserFacebookProfile
		Date wDate = friend.getBirthdayAsDate();
		String wDate2 = friend.getBirthday();
		// Tratamento de erros da data, como explicado no método
		// saveUserFacebookProfile
		if (wDate2 == null) {
			friends_fp.setBirthday(wDate2);
		} else {
			String[] wDate3 = wDate2.split("(?<=\\G.{1})");
			if (wDate3.length == 5) {
				friends_fp.setBirthday(wDate2);
			} else {
				DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
				String date = formatter.format(wDate);
				friends_fp.setBirthday(date);
			}
		}

		return friends_fp;
	}

	// Esse método pega os dados que estão em FacebookName.txt,
	// FacebookBluetooth.txt e FacebookBirthday.txt
	// e os guarda em uma lista de objetos FacebookProfile para serem usados
	// posteriormente
	// pela classe FriendInference para geração de PossibleTags.
	public ArrayList<FacebookProfile> getFacebookInstances(String nome)
			throws FileNotFoundException, IOException {
		ArrayList<FacebookProfile> fp = new ArrayList<FacebookProfile>();
		ArrayList<String> name = FacebookData.readFacebookName(nome);
		ArrayList<String> bluetooth = FacebookData.readFacebookBluetooth(nome);
		ArrayList<String> birthday = FacebookData.readFacebookBirthday(nome);
		int size = name.size();

		// Transforma a data de String para Date
		DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);

		ArrayList<Date> btd = new ArrayList<Date>();

		for (int i = 0; i < birthday.size(); i++) {
			Date bty = null;
			try {

				bty = df.parse(birthday.get(i));
			} catch (ParseException ex) {
				// System.out.println(TagConstants.WRONGFACEBOOKDATEFORMAT);
			} catch (NullPointerException e) {
				// System.out.println(TagConstants.NULLFACEBOOKDATEFORMAT);
			}
			btd.add(bty);
		}
		for (int i = 0; i < size; i++) {
			FacebookProfile face = new FacebookProfile();
			face.setName(name.get(i));
			face.setBluetooth(bluetooth.get(i));
			face.setBirthday(btd.get(i));
			fp.add(face);
		}

		return fp;
	}
}
